package com.ruoyi.system.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SyncLog;
import com.ruoyi.system.domain.SyncServer;
import com.ruoyi.system.domain.SyncTask;
import com.ruoyi.system.domain.vo.DbInfo;
import com.ruoyi.system.domain.vo.TableInfo;
import com.ruoyi.system.mapper.SyncTaskMapper;
import com.ruoyi.system.service.ISyncLogService;
import com.ruoyi.system.service.ISyncServerService;
import com.ruoyi.system.service.ISyncTaskService;

/**
 * 同步任务Service业务层处理
 * 
 * @author ruoyi
 */
@Service
public class SyncTaskServiceImpl implements ISyncTaskService 
{
    @Autowired
    private SyncTaskMapper syncTaskMapper;
    
    @Autowired
    private ISyncServerService syncServerService;
    
    @Autowired
    private ISyncLogService syncLogService;

    /**
     * 查询同步任务
     * 
     * @param syncId 同步任务ID
     * @return 同步任务
     */
    @Override
    public SyncTask selectSyncTaskById(Long syncId)
    {
        return syncTaskMapper.selectSyncTaskById(syncId);
    }

    /**
     * 查询同步任务列表
     * 
     * @param syncTask 同步任务
     * @return 同步任务
     */
    @Override
    public List<SyncTask> selectSyncTaskList(SyncTask syncTask)
    {
        List<SyncTask> list = syncTaskMapper.selectSyncTaskList(syncTask);
        // 填充源服务器名称和目标服务器名称
        for (SyncTask task : list)
        {
            if (task.getSourceServerId() != null)
            {
                SyncServer sourceServer = syncServerService.selectSyncServerById(task.getSourceServerId());
                if (sourceServer != null)
                {
                    task.setSourceServer(sourceServer.getServerName());
                }
            }
            
            if (task.getTargetServerId() != null)
            {
                SyncServer targetServer = syncServerService.selectSyncServerById(task.getTargetServerId());
                if (targetServer != null)
                {
                    task.setTargetServer(targetServer.getServerName());
                }
            }
        }
        return list;
    }

    /**
     * 新增同步任务
     * 
     * @param syncTask 同步任务
     * @return 结果
     */
    @Override
    public int insertSyncTask(SyncTask syncTask)
    {
        syncTask.setCreateTime(DateUtils.getNowDate());
        syncTask.setCreateBy(SecurityUtils.getUsername());
        return syncTaskMapper.insertSyncTask(syncTask);
    }

    /**
     * 修改同步任务
     * 
     * @param syncTask 同步任务
     * @return 结果
     */
    @Override
    public int updateSyncTask(SyncTask syncTask)
    {
        syncTask.setUpdateTime(DateUtils.getNowDate());
        syncTask.setUpdateBy(SecurityUtils.getUsername());
        return syncTaskMapper.updateSyncTask(syncTask);
    }

    /**
     * 批量删除同步任务
     * 
     * @param syncIds 需要删除的同步任务ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteSyncTaskByIds(Long[] syncIds)
    {
        // 删除相关的日志
        for (Long syncId : syncIds)
        {
            syncLogService.deleteSyncLogBySyncId(syncId);
        }
        return syncTaskMapper.deleteSyncTaskByIds(syncIds);
    }

    /**
     * 删除同步任务信息
     * 
     * @param syncId 同步任务ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteSyncTaskById(Long syncId)
    {
        // 删除相关的日志
        syncLogService.deleteSyncLogBySyncId(syncId);
        return syncTaskMapper.deleteSyncTaskById(syncId);
    }
    
    /**
     * 执行同步任务
     * 
     * @param syncId 同步任务ID
     * @return 结果
     */
    @Override
    @Transactional
    public boolean runSyncTask(Long syncId)
    {
        SyncTask task = syncTaskMapper.selectSyncTaskById(syncId);
        if (task == null)
        {
            throw new ServiceException("同步任务不存在");
        }
        
        // 检查服务器是否存在
        SyncServer sourceServer = syncServerService.selectSyncServerById(task.getSourceServerId());
        if (sourceServer == null)
        {
            throw new ServiceException("源服务器不存在");
        }
        
        SyncServer targetServer = syncServerService.selectSyncServerById(task.getTargetServerId());
        if (targetServer == null)
        {
            throw new ServiceException("目标服务器不存在");
        }
        
        // 记录开始日志
        SyncLog startLog = new SyncLog();
        startLog.setSyncId(syncId);
        startLog.setSyncName(task.getSyncName());
        startLog.setOperationType("0"); // 同步开始
        startLog.setStartTime(new Date());
        startLog.setStatus("0"); // 正常
        syncLogService.insertSyncLog(startLog);
        
        try
        {
            // 更新任务的最后执行时间
            task.setLastRunTime(new Date());
            syncTaskMapper.updateSyncTaskLastRunTime(task);
            
            // 根据同步类型执行不同的同步逻辑
            if ("0".equals(task.getSyncType()))
            {
                // 数据库同步
                syncDatabase(task, sourceServer, targetServer);
            }
            else if ("1".equals(task.getSyncType()))
            {
                // 文件同步
                syncFiles(task, sourceServer, targetServer);
            }
            
            // 记录完成日志
            SyncLog endLog = new SyncLog();
            endLog.setSyncId(syncId);
            endLog.setSyncName(task.getSyncName());
            endLog.setOperationType("1"); // 同步完成
            endLog.setStartTime(startLog.getStartTime());
            endLog.setEndTime(new Date());
            endLog.setCostTime((endLog.getEndTime().getTime() - startLog.getStartTime().getTime()) / 1000);
            endLog.setStatus("0"); // 正常
            syncLogService.insertSyncLog(endLog);
            
            return true;
        }
        catch (Exception e)
        {
            // 记录错误日志
            SyncLog errorLog = new SyncLog();
            errorLog.setSyncId(syncId);
            errorLog.setSyncName(task.getSyncName());
            errorLog.setOperationType("2"); // 同步错误
            errorLog.setStartTime(startLog.getStartTime());
            errorLog.setEndTime(new Date());
            errorLog.setCostTime((errorLog.getEndTime().getTime() - startLog.getStartTime().getTime()) / 1000);
            errorLog.setStatus("1"); // 异常
            errorLog.setDetail(StringUtils.substring(e.getMessage(), 0, 2000)); // 限制长度
            syncLogService.insertSyncLog(errorLog);
            
            throw new ServiceException("同步执行失败: " + e.getMessage());
        }
    }
    
    /**
     * 执行数据库同步
     */
    private void syncDatabase(SyncTask task, SyncServer sourceServer, SyncServer targetServer)
    {
        // 实际项目中需要根据不同数据库类型实现具体的同步逻辑
        // 本示例只做流程演示，不实现实际的数据库同步
        if (StringUtils.isEmpty(task.getSourceDb()) || StringUtils.isEmpty(task.getTargetDb()))
        {
            throw new ServiceException("源数据库或目标数据库不能为空");
        }
        
        if (StringUtils.isEmpty(task.getSourceTables()))
        {
            throw new ServiceException("源数据表不能为空");
        }
        
        // 数据库同步的具体逻辑实现
        // ...
    }
    
    /**
     * 执行文件同步
     */
    private void syncFiles(SyncTask task, SyncServer sourceServer, SyncServer targetServer)
    {
        // 实际项目中需要实现文件同步的具体逻辑
        // 本示例只做流程演示，不实现实际的文件同步
        if (StringUtils.isEmpty(task.getSourcePath()) || StringUtils.isEmpty(task.getTargetPath()))
        {
            throw new ServiceException("源文件路径或目标文件路径不能为空");
        }
        
        // 文件同步的具体逻辑实现
        // ...
    }
    
    /**
     * 获取服务器的数据库列表
     * 
     * @param serverId 服务器ID
     * @return 数据库列表
     */
    @Override
    public List<DbInfo> getDbList(Long serverId)
    {
        // 实际项目中需要实现获取数据库列表的逻辑
        // 本示例返回模拟数据
        List<DbInfo> dbList = new ArrayList<>();
        
        SyncServer server = syncServerService.selectSyncServerById(serverId);
        if (server != null && "0".equals(server.getServerType()))
        {
            // 假设服务器是数据库服务器
            DbInfo db1 = new DbInfo();
            db1.setDbId("db1");
            db1.setDbName("数据库1");
            dbList.add(db1);
            
            DbInfo db2 = new DbInfo();
            db2.setDbId("db2");
            db2.setDbName("数据库2");
            dbList.add(db2);
        }
        
        return dbList;
    }
    
    /**
     * 获取数据库的表列表
     * 
     * @param dbId 数据库ID
     * @return 表列表
     */
    @Override
    public List<TableInfo> getTablesByDb(String dbId)
    {
        // 实际项目中需要实现获取表列表的逻辑
        // 本示例返回模拟数据
        List<TableInfo> tableList = new ArrayList<>();
        
        if ("db1".equals(dbId))
        {
            TableInfo table1 = new TableInfo();
            table1.setTableName("sys_user");
            table1.setTableComment("用户表");
            table1.setTableRows(100L);
            tableList.add(table1);
            
            TableInfo table2 = new TableInfo();
            table2.setTableName("sys_role");
            table2.setTableComment("角色表");
            table2.setTableRows(10L);
            tableList.add(table2);
        }
        else if ("db2".equals(dbId))
        {
            TableInfo table1 = new TableInfo();
            table1.setTableName("sys_menu");
            table1.setTableComment("菜单表");
            table1.setTableRows(50L);
            tableList.add(table1);
            
            TableInfo table2 = new TableInfo();
            table2.setTableName("sys_dept");
            table2.setTableComment("部门表");
            table2.setTableRows(20L);
            tableList.add(table2);
        }
        
        return tableList;
    }
} 